home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
stufit2.zip
/
STUFIT2.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-07-26
|
29KB
|
1,038 lines
;==========================================================================
;== ==
;== STUFIT ==
;==========================================================================
;Utility to move designated files to the inner tracks of a disk.
;
;Disassembled and heavily hacked, with most of the significant changes
;annotated with the "v1.x" comments.
;
;Incorporating DOS v3.x/4.x patches from:
; Hylton Boothroyd, University of Warwick, 890710
;See his notes at the end.
;
; - No need to reset DTA for each file.
; Just doing it once now (at Find_First)
;
; - Confirmed via tests, no need to "force DOS next free space"
; at every run (as in Hylton's original patch).
; Just doing it once now (at Check_DOS_Version)
;
;I've noticed the program halts when it hits a file too big to relocate
;(e.g., free space is less than target file size).
;This is as it should be .. but halting right there is not so very smart:
;we should be smart enough to go on beyond that too-big file in case
;there are smaller ones that WILL fit.
;
;In the meantime, this utility will work best if you use a directory sorting
;utility (like Norton's Utilities) to sort in order of file size
;(smallest files first).
;
;This enables the "Find First" and "Find Next" functions to pick up
;files in an order most likely to maximize the number of files that can
;be moved to the innermost tracks. (Assuming you have a free space
;limitation that prohibits moving ALL files.)
;
;
;We're also sticking with the sheer brute-force method of forcing
;our "next free space" to disk end (via creating a temporary free-space
;holding file that gobbles ALL the free space on the disk .. except for
;the space required for the target file copy).
;
;There oughtta be a way to fool DOS into finding free space working
;backwards from the inside tracks, or from the last new file we created
;during relocation. Unfortunately, I can't think of any way!
;
;
;David Kirschbaum
;Toad Hall
;kirsch@braggvax.ARPA
CR equ 0DH
LF equ 0AH
CSEG SEGMENT PUBLIC PARA 'CODE'
ASSUME CS:CSEG, DS:CSEG, ES:CSEG
org 0
cseg_org label byte ;needed to help MASM
;figure buffer size v1.1
org 80H
cmdline label byte ;v1.1
org 100h
StufIt proc near
jmp Start
;v1.2 Some data previously scattered around the program
; consolidated here.
ourDTA label byte ;working dta
db 'dta2dta2dta2dta2dta2dta2dta2dt'
;DTA+30 ;file name psn
;within DTA
db 'a2'
db 'dta2dta2dta2dta2dta2dta2dta2dta2'
db 'dta2dta2dta2dta2dta2dta2dta2dta2'
db 'dta2dta2dta2dta2dta2dta2dta2dta2'
targetname label byte ;quite a buffer!
db 'filenamefilenamefilenamefilename'
db 'filenamefilenamefilenamefilename'
db 'filenamefilenamefilenamefilename'
db 'filenamefilenamefilenamefilename'
;for current filename display
namelen dw 0 ;length
nameptr dw targetname ;ptr to filename
StufIt endp
;==========================================================================
; SUBROUTINE
;==========================================================================
err2 db '-File not found-',CR,LF,'$'
err3 db '-Path not found-',CR,LF,'$'
err4 db '-Too many open files (no handles left)-',CR,LF,'$'
err5 db '-Access denied-',CR,LF,'$'
err6 db '-Invalid handle-',CR,LF,'$'
err0C db '-Invalid access code-',CR,LF,'$'
err11 db '-Not same device-',CR,LF,'$'
err12 db '-No more files-',CR,LF,'$'
err1C db '-Write error-',CR,LF,'$' ;v1.1
errunk db '-Unrecognized error code-'
crlf$ db CR,LF,'$' ;share this v1.1
;Vastly tightened
;Enter with:
; AX = file error
; DX = first error message
Rpt_Error proc near ;v1.1
mov bx,ax ;save error value v1.1
mov si,dx ;and msg ptr v1.1
mov dx,offset crlf$ ;always a new line v1.1
mov ah,9 ;display msg v1.1
int 21H ; v1.1
mov dx,si ;first msg ptr v1.1
mov ah,9 ;display msg v1.1
int 21H ; v1.1
mov ax,bx ;restore error v1.1
mov dx,offset err2 ;'file not found'
cmp al,2
jz Pr_ErrMsg
mov dx,offset err3 ;'Path not found'
cmp al,3
jz Pr_ErrMsg
mov dx,offset err4 ;'Too many open files'
cmp al,4
jz Pr_ErrMsg
mov dx,offset err5 ;'Access denied'
cmp al,5
jz Pr_ErrMsg
mov dx,offset err6 ;'Invalid handle'
cmp al,6
jz Pr_ErrMsg
mov dx,offset err0C ;'Invalid access code'
cmp al,0CH
jz Pr_ErrMsg
mov dx,offset err11 ;'Not same device'
cmp al,11H
jz Pr_ErrMsg
mov dx,offset err12 ;'No more files'
cmp al,12H
jz Pr_ErrMsg
mov dx,offset err1C ;'Write error' v1.1
cmp al,1CH ; v1.1
jz Pr_ErrMsg ; v1.1
mov dx,offset errunk ;'Unknown error'
Pr_ErrMsg:
mov bx,ax ;save error value v1.1
mov ah,9 ;display msg
int 21H
mov ax,bx ;restore error value v1.1
stc ;always return CF set v1.1
ret
Rpt_Error endp
;==========================================================================
; SUBROUTINE
;==========================================================================
;Wonder why he bothered with these default values?
bytesPerSector dw 0 ;was 200h v1.2
sectorsPerCluster dw 0 ;was 8 v1.2
bytesPerCluster dw 0 ;was 1000h v1.2
nrClusters dw 0 ;was 0A1AH v1.2
avail$ db 'avail: $' ; v1.1
availClusters dw 0
Get_FreeSpace proc near
mov ah,36h ;get free space
xor dx,dx ;current drive v1.1
int 21h
jnc Loc_12 ;got it ok
mov dx,offset avail$ ;'avail: '
jmp Rpt_Error ;display error msg, v1.1
;return from there CF set
Loc_12:
mov availClusters,bx ;available cluster count
mov nrClusters,dx ;total clusters
mov bytesPerSector,cx ;bytes per sector
mov sectorsPerCluster,ax ;sectors per cluster
mul cx
mov bytesPerCluster,ax ;bytes per cluster
clc ;return CF clear
ret
Get_FreeSpace endp
;==========================================================================
; SUBROUTINE
;==========================================================================
getfirst$ db 'getfirst: $' ;v1.1
getnext$ db 'getnext: $' ;v1.1
;Code for Find First and Find Next
Find_File proc near
Find_Next:
;v1.2 I wonder why we keep resetting the DTA?
; We did it once at Find_First .. why again and again?
; Trying this without the DTA reset
Comment ~
mov dx,offset ourDTA ;working DTA
mov ah,1AH ;set DTA to DS:DX
int 21h
jc FindNext_Fail ;failed
Comment ends ~
mov ah,4FH ;find next filename
int 21h
;v1.1 jc FindNext_Fail ;failed
;Wrongo! Find Next does NOT use the CF to indicate success/failure.
;Instead, AX returns a value (0 if found).
or ax,ax ;found it?
jnz FindNext_Fail ;nope, die
mov si,nameptr ;get ptr to filename
jmp short Find_Common ; and continue
FindNext_Fail:
mov dx,offset getnext$ ;'getnext: '
jmp Rpt_Error ;display file error v1.1
;return from there CF set
;Enter here for the Find First.
Find_First:
mov dx,offset ourDTA ;working DTA
mov ah,1AH ;set DTA to DS:DX
int 21h
jc FindFirst_Fail ;failed v1.1
mov dx,offset targetname ;filename buffer
xor cx,cx ;no special attribs
mov ah,4Eh ;find first
int 21h
;v1.1 jnc Loc_19 ;found it
;Wrongo! Find First doesn't use the carry flag to indicate
;success or failure! Results are in AX!
or ax,ax ;0 means success v1.1
jnz FindFirst_Fail ;didn't find it v1.1
mov si,offset targetname-1 ;filename buffer-1
mov cx,namelen ;name length v1.1
add si,cx ;bump filename ptr also v1.1
std ;move backwards
LocLoop_20:
lodsb ;snarf target filename char
cmp al,'\' ;part of a path?
je NameStart_21 ;yep
cmp al,'/' ;could be using this as path
je NameStart_21 ;yep
cmp al,':' ;how about a drive separator?
je NameStart_21 ;yep
loop LocLoop_20 ;just a name char
dec si ;adjust from last lodsb
NameStart_21:
mov nameptr,si ;save ptr to filename start
;Common code for Find_First and Find_Next
Find_Common:
mov di,si ;target filename start
mov si,offset ourDTA+30 ;30 bytes into workin